#!/usr/bin/env python

import pygtk

pygtk.require('2.0')
import gtk
import os
import commands, subprocess
import pexpect
import pySu

class Row:
    nameEntry = gtk.Entry()
    valueEntry = gtk.Entry()
    deleteButton = gtk.Button('delete')
    pass

class MainWindow:
    rows = []
    def callback(self, widget, data=None):
        if widget.get_active():
            self.shells.append(widget.get_label())
        else:
            self.shells.remove(widget.get_label())
        print self.shells

    def varalias(self, widget, data=None):
        if widget.get_active():
            self.varNameLabel.set_text(data + " name:")
            self.varValueLabel.set_text(data + " value:")
            self.alias = "Alias" == data

    def select_all_callback(self, widget, usersButtonList):
        for userButton in usersButtonList:
            userButton.set_active(True)

    def deselect_all_callback(self, widget, usersButtonList):
        for userButton in usersButtonList:
            userButton.set_active(False)

    def responseToDialog(self, entry, dialog, response):
        dialog.response(response)

    def check_root_permissions(self):
        dialog = gtk.MessageDialog(
            None,
            gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
            gtk.MESSAGE_QUESTION,
            gtk.BUTTONS_OK,
            None)
        dialog.set_markup('Please enter a <b>root</b> password:')
        passwordEntry = gtk.Entry()
        passwordEntry.set_visibility(False)
        passwordEntry.connect("activate", self.responseToDialog, dialog, gtk.RESPONSE_OK)
        dialogHBox = gtk.HBox()
        dialogHBox.pack_start(gtk.Label("Password:"), False, 5, 5)
        dialogHBox.pack_end(passwordEntry)
        dialog.vbox.pack_end(dialogHBox, True, True, 0)
        dialog.show_all()
        dialog.run()
        p = passwordEntry.get_text()
        pySu.su('whoami > who_test', p)
        if not os.path.exists('who_test'):
            md = gtk.MessageDialog(None,
                gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
                gtk.BUTTONS_CLOSE, "Wrong root password!")
            md.run()
            md.destroy()
        else:
            self.password = p
            #pySu.su('rm -f who_test', self.password) #odkomentowac jakby ponizsze nie dzialalo(???)
            os.system('rm -f who_test')
        dialog.destroy()

    def file_exists(self, user, filename):
        pySu.su('./fileexists.sh ' + filename, self.password)
        if not os.path.exists('file_exists'):
            return False
            #pySu.su('rm -f file_exists', self.password) #odkomentowac jakby ponizsze nie dzialalo(???)
        os.system('rm -f file_exists')
        return True

    def save_users(self, widget, args):
        self.users = [button.get_label() for button in args[0] if button.get_active()]
        args[1].destroy()
        print self.users

    def make_tmp(self, filepath):#, name, value):
        self.save_values_to_tmp()
        if(self.alias):
            scriptname = "./alias.sh"
        else:
            scriptname = "./variable.sh"
        if not self.password == '':
            pySu.su(scriptname + ' ' + filepath + ' > ' + filepath + '.tmp', self.password)
            pySu.su('cp ' + filepath + ' .', self.password)
            pySu.su('cp ' + filepath + '.tmp .', self.password)
        else:
            os.system(scriptname + ' ' + filepath + ' > ' + filepath + '.tmp')
            os.system('cp ' + filepath + ' .')
            os.system('cp ' + filepath + '.tmp .')

    def files_row_activated(self, treeview, path, column):
        select1, select2 = treeview.get_selection().get_selected_rows()
        filepath = select1[select2[0][0]][1]
        self.make_tmp(filepath)
        subprocess.Popen(args=["gnome-terminal", "--command=vimdiff .bashrc .bashrc.tmp"])

    def selected_users_toggled(self, widget, data=None):
        if self.selUsersRadioButton.get_active():
            self.users = self.users_old
            self.selectUsersButton.set_sensitive(True)
        else:
            self.users_old = self.users
            self.users = commands.getoutput('awk -F\':\' \'{ print $1}\' /etc/passwd').split('\n')
            self.selectUsersButton.set_sensitive(False)

    def save_clicked(self, widget, data=None):
        print self.users
        for user in self.users:
            homeDir = commands.getoutput('awk -F\':\' \'{ if ($1 == "' + user + '") print $6}\' /etc/passwd')
            if homeDir[len(homeDir) - 1] != "/":
                homeDir = ''.join([homeDir, "/"])
            for shell in self.shells:
                filepath = homeDir + '.' + shell + 'rc'
                self.make_tmp(filepath)
                command = 'mv ' + filepath + '.tmp ' + filepath
                if not self.password == '':
                    pySu.su(command, self.password)
		    if not homeDir == commands.getoutput('awk -F\':\' \'{ if ($1 == "root") print $6}\' /etc/passwd'):
		    	pySu.su('chown ' + user + ' ' + filepath, self.password)
                else:
                    os.system(command)
        print 'SAVE!'

    def select_clicked(self, widget, data=None):
        allUsers = commands.getoutput('awk -F\':\' \'{ print $1}\' /etc/passwd').split('\n')
        usersButtonsList = []
        usersWin = gtk.Window()
        usersWin.show()
        mainVBox = gtk.VBox(False, 0)
        usersWin.add(mainVBox)
        selectAllButton = gtk.Button('Select all')
        selectAllButton.connect("clicked", self.select_all_callback, usersButtonsList)
        deselectAllButton = gtk.Button('Deselect all')
        deselectAllButton.connect("clicked", self.deselect_all_callback, usersButtonsList)
        mainVBox.pack_start(selectAllButton, True, True, 0)
        mainVBox.pack_start(deselectAllButton, True, True, 0)
        scrolled_window = gtk.ScrolledWindow()
        scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        mainVBox.pack_start(scrolled_window, True, True, 0)
        vbox = gtk.VBox(False, 0)
        scrolled_window.add_with_viewport(vbox)
        for name in allUsers:
            button = gtk.CheckButton(name)
            if name in self.users:
                button.set_active(True)
            vbox.pack_start(button, True, True, 0)
            usersButtonsList.append(button)
        hbox = gtk.HBox(False, 0)
        saveButton = gtk.Button('Save')
        saveButton.connect("clicked", self.save_users, [usersButtonsList, usersWin])
        cancelButton = gtk.Button('Cancel')
        cancelButton.connect("clicked", lambda w: usersWin.destroy())
        hbox.pack_start(saveButton, True, True, 0)
        hbox.pack_start(cancelButton, True, True, 0)
        mainVBox.pack_start(hbox, True, True, 0)
        usersWin.show_all()

    def review_clicked(self, widget, data=None):
        reviewWin = gtk.Window()
        reviewWin.show()
        vbox = gtk.VBox(False, 0)
        reviewWin.add(vbox)
        vbox.pack_start(gtk.Label("The following files gonna be changed:"), True, True, 0)

        rootPassChecked = False
        files = gtk.ListStore(str, str)
        for user in self.users:
            homeDir = commands.getoutput('awk -F\':\' \'{ if ($1 == "' + user + '") print $6}\' /etc/passwd')
            if homeDir[len(homeDir) - 1] != "/":
                homeDir = ''.join([homeDir, "/"])
            for shell in self.shells:
                filename = homeDir + '.' + shell + 'rc'
                try:
                    open(filename, 'r+')
                    files.append([user, filename])
                except IOError:
                    if self.password == '' and rootPassChecked == False: #sprawdzamy czy user zna haslo roota
                        self.check_root_permissions()
                        rootPassChecked = True
                        if not self.password == '':
                            if self.file_exists(user, filename):
                                files.append([user, filename])
                            else:
                                print "skipping file: " + filename + " - file doesn't exist!"
                    elif not self.password == '': #juz wiemy ze user zna haslo roota
                        #sprawdzamy czy plik istnieje
                        if self.file_exists(user, filename):
                            files.append([user, filename])
                        else:
                            print "skipping file: " + filename + " - file doesn't exist!"
                    else: #user juz probowal podac haslo roota, ale mu nie wyszlo
                        print "skipping file: " + filename + " either user has no permission or file doesn't exist!"

        treeview = gtk.TreeView(files)
        scrolled_window = gtk.ScrolledWindow()
        scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scrolled_window.set_size_request(400, 300)
        scrolled_window.add_with_viewport(treeview)

        cell = gtk.CellRendererText()
        column = gtk.TreeViewColumn("User", cell)
        column.add_attribute(cell, "text", 0)
        treeview.append_column(column)
        cell = gtk.CellRendererText()
        column = gtk.TreeViewColumn("File", cell)
        column.add_attribute(cell, "text", 1)
        treeview.append_column(column)

        treeview.connect("row-activated", self.files_row_activated)

        vbox.pack_start(scrolled_window, True)

        button = gtk.Button("OK")
        button.connect("clicked", lambda w: reviewWin.destroy())
        vbox.pack_start(button, True, True, 0)
        reviewWin.show_all()

    def on_close(self, widget):
        os.system('rm -f .bashrc')
        os.system('rm -f .bashrc.tmp')
        gtk.main_quit()

    def add_clicked(self, widget):
        # height of textfields and button
        height = 35
        row = Row()
        row.nameEntry = gtk.Entry()
        row.nameEntry.set_text("name")
        self.vboxTopLeft.pack_start(row.nameEntry, False, True, 0)
        row.nameEntry.show()
        row.nameEntry.set_size_request(0, height)

        row.valueEntry = gtk.Entry()
        row.valueEntry.set_text("value")
        self.vboxTopCenter.pack_start(row.valueEntry, False, True, 0)
        row.valueEntry.show()
        row.valueEntry.set_size_request(0, height)

        row.deleteButton = gtk.Button('delete')
        self.vboxTopRight.pack_start(row.deleteButton, False, True, 0)
        row.deleteButton.show()
        row.deleteButton.connect("clicked", self.delete_clicked)
        row.deleteButton.set_size_request(0, height)

        self.rows.append(row)

    def delete_clicked(self, widget):
        # nie pozwalamy usunac jedynej linii
        if len(self.rows) == 1:
            return
        for row in self.rows:
            if row.deleteButton == widget:
                row.nameEntry.hide()
                row.valueEntry.hide()
                row.deleteButton.hide()
                self.rows.remove(row)
                return

    def save_values_to_tmp(self):
        f = open('values.tmp', 'w')
        for row in self.rows:
            name = row.nameEntry.get_text()
            value = row.valueEntry.get_text().replace('"', '\\"');
            f.write(name + ' ' + value + '\n')
        f.close()

    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect("destroy", self.on_close)
        self.window.set_title("Da Linux Pimpin'")
        self.window.set_resizable(False)
        #lista z loginami userow, ktorym dodajemy zmienna/alias:
        self.users = commands.getoutput('awk -F\':\' \'{ print $1}\' /etc/passwd').split('\n')
        self.users_old = [] #lista jak wyzej, tylko zapamietuje ostatnio wybranych uzytkownikow
        self.shells = [] #lista z zaznaczonymi shellami, do ktorych dodajemy zmienna/alias
        self.password = '' #haslo roota

        # glowne hvbox i vbox
        hbox0 = gtk.VBox(False, 0)
        self.window.add(hbox0)

        vbox0 = gtk.VBox(False, 0)
        hbox0.pack_start(vbox0, True, True, 0)

        vbox1 = gtk.VBox(False, 0)
        hbox0.pack_start(vbox1, True, True, 0)

        self.vboxTopLeft = gtk.VBox(False, 0)
        self.vboxTopCenter = gtk.VBox(False, 0)
        self.vboxTopRight = gtk.VBox(False, 0)

        self.hbox1 = gtk.HBox(False, 0)
        vbox0.pack_start(self.hbox1, True, True, 0)

        self.hbox1.pack_start(self.vboxTopLeft, True, True, 0)
        self.hbox1.pack_start(self.vboxTopCenter, True, True, 0)
        self.hbox1.pack_start(self.vboxTopRight, True, True, 0)

        # labels
        self.varNameLabel = gtk.Label("Variable name:")
        self.vboxTopLeft.pack_start(self.varNameLabel, True, True, 0)
        self.varValueLabel = gtk.Label("Variable value:")
        self.vboxTopCenter.pack_start(self.varValueLabel, True, True, 0)
        deleteLabel = gtk.Label("Delete")
        self.vboxTopRight.pack_start(deleteLabel, True, True, 0)

        self.add_clicked(None)

        self.varNameEntry = self.rows[0].nameEntry
        self.varValueEntry = self.rows[0].valueEntry

        hbox3 = gtk.HBox(False, 0)
        vbox1.pack_start(hbox3, True, True, 0)

        vbox2 = gtk.VBox(False, 0)
        hbox3.pack_start(vbox2, True, True, 0)
        button = gtk.CheckButton("bash")
        button.connect("toggled", self.callback, "bash")
        vbox2.pack_start(button, True, True, 0)
        button = gtk.CheckButton("sh")
        button.connect("toggled", self.callback, "sh")
        vbox2.pack_start(button, True, True, 0)
        button = gtk.CheckButton("csh")
        button.connect("toggled", self.callback, "csh")
        vbox2.pack_start(button, True, True, 0)

        hbox4 = gtk.HBox(False, 0)
        vbox2.pack_start(hbox4, True, True, 0)
        button = gtk.Button("Save")
        button.connect("clicked", self.save_clicked)
        hbox4.pack_start(button, True, True, 0)
        self.selectUsersButton = gtk.Button("Select users")
        self.selectUsersButton.set_sensitive(False)
        self.selectUsersButton.connect("clicked", self.select_clicked)
        hbox4.pack_start(self.selectUsersButton, True, True, 0)
        button = gtk.Button("Review")
        button.connect("clicked", self.review_clicked)
        hbox4.pack_start(button, True, True, 0)

        vbox3 = gtk.VBox(False, 0)
        hbox3.pack_start(vbox3, True, True, 0)
        button = gtk.RadioButton(None, "For all users (if you ain't no root, don't touch it!)")
        vbox3.pack_start(button, True, True, 0)
        self.selUsersRadioButton = gtk.RadioButton(button, "For selected users")
        self.selUsersRadioButton.connect("toggled", self.selected_users_toggled)
        vbox3.pack_start(self.selUsersRadioButton, True, True, 0)

        vbox4 = gtk.VBox(False, 0)
        hbox3.pack_start(vbox4, True, True, 0)
        addButton = gtk.Button('Add')
        addButton.connect("clicked", self.add_clicked)
        vbox4.pack_start(addButton, True, True, 0)
        button = gtk.RadioButton(None, "Variable");
        button.connect("toggled", self.varalias, "Variable")
        vbox4.pack_start(button, True, True, 0)
        self.aliasButton = gtk.RadioButton(button, "Alias")
        self.aliasButton.connect("toggled", self.varalias, "Alias")
        vbox4.pack_start(self.aliasButton, True, True, 0)
        self.alias = False

        self.window.show_all()

    def main(self):
        gtk.main()

if __name__ == "__main__":
    hello = MainWindow()
    hello.main()

